package com.dongnao.network.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author sjy
 * @date 2024年05月10日 13:40
 */
public class SelectorServer {

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //创建Selector
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        serverSocketChannel.configureBlocking(false);//设置为非阻塞模式
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));//绑定端口
        System.out.println("服务端启动");
        while (true) {
            int readyChannels = selector.select();//会阻塞，直到有事件触发
            if (readyChannels == 0) {
                continue;
            }
            System.out.println("触发的事件数：" + readyChannels);
            //获取被触发的事件集合
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isAcceptable()) {
                    System.out.println("新的客户端发起连接事件");
                    SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isConnectable()) {
                    //连接到远程服务端，只在客户端异步连接时生效
                    System.out.println("客户端连接到了服务端");
                } else if (key.isReadable()) {
                    //SocketChannel 中有数据可以读
                } else if (key.isWritable()) {
                    //SocketChannel 可以开始写入数据
                }

                //将已处理的事件移除，否则认为没处理过，再处理一遍
                iterator.remove();
            }
        }
    }
}
